﻿using Moq;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TabbedTemplate.Models;
using TabbedTemplate.Services;
using TabbedTemplate.ViewModels;
using Xamarin.Forms.Extended;

namespace UnitTest.ViewModels
{
    public class TestIndexPageViewModel
    {
        [Test]
        public async Task StoreTappedCommandTest()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;

            var punchNavigationServiceMock = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;

            var StoreToTap = new Store();
            var indexPageViewModel =
                new IndexPageViewModel(null, mockPunchNavigationService, mockPreferenceStorage, null, null);
            await indexPageViewModel.StoreTappedCommandFunction(StoreToTap);

            punchNavigationServiceMock.Verify(
                p => p.NavigateToAsync(
                    ContentNavigationConstant.StorePunchesPage, StoreToTap),
                Times.Once);
        }

        [Test]
        public async Task PageAppearingCommandTest1()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var locationMock = new Mock<ILocationService>();
            var mockLocationService = locationMock.Object;
            var beijingCacheServiceMock = new Mock<IBeijingCacheService>();
            var mockBeijingCacheService = beijingCacheServiceMock.Object;
            var tag = Tag.ChineseRestuarant;
            var storeService = new StoreService(mockPreferenceStorage, mockLocationService);
            preferenceStorageMock.Setup(p => p.Get("newQuery", true)).Returns(true);
            preferenceStorageMock.Setup(p => p.Get("Latitude", double.MaxValue)).Returns(1.0);
            beijingCacheServiceMock.Setup(p => p.BeijingInitialized()).Returns(false);

            var statuslist = new List<string>();
            var indexPageViewModel =
                new IndexPageViewModel(null, null,
                    mockPreferenceStorage, mockBeijingCacheService, mockLocationService);
            indexPageViewModel.Tag = tag;
        }

        [Test]
        public async Task PageAppearingCommandTest()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var locationMock = new Mock<ILocationService>();
            var mockLocationService = locationMock.Object;
            var beijingCacheServiceMock = new Mock<IBeijingCacheService>();
            var mockBeijingCacheService = beijingCacheServiceMock.Object;
            var tag = Tag.ChineseRestuarant;
            var storeService = new StoreService(mockPreferenceStorage, mockLocationService);
            var stores = new List<Store>();
            for (int i = 0; i < 9; i++)
            {
                stores.Add(new Store());
            }
            preferenceStorageMock.Setup(p => p.Get("newQuery", true)).Returns(true);
            preferenceStorageMock.Setup(p => p.Get("Latitude", double.MaxValue)).Returns(Double.MaxValue);
            beijingCacheServiceMock.Setup(p => p.BeijingInitialized()).Returns(false);
            beijingCacheServiceMock.Setup(p =>
                    p.GetBeijingStoreByTagAsync("美食;" + tag.CnName, It.IsAny<int>(), StoreService.PageSize))
                .ReturnsAsync(stores);
            var statusList = new List<string>();

            var indexPageViewModel =
                new IndexPageViewModel(null, null,
                    mockPreferenceStorage, mockBeijingCacheService, mockLocationService);
            indexPageViewModel.Tag = tag;
            indexPageViewModel.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == nameof(TabbedTemplate.ViewModels.IndexPageViewModel.Status))
                {
                    statusList.Add(indexPageViewModel.Status);
                }
            };
            await indexPageViewModel.GetStoresFromWebCommandFunctionAsync();
            Assert.AreEqual(statusList[1], IndexPageViewModel.NoMoreResult);
        }



        [Test]
        public async Task TestPageAppearingCommandNoLocation()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var locationMock = new Mock<ILocationService>();
            var mockLocationService = locationMock.Object;
            var beijingCacheServiceMock = new Mock<IBeijingCacheService>();
            var mockBeijingCacheService = beijingCacheServiceMock.Object;
            var tag = Tag.ChineseRestuarant;
            var storeService = new StoreService(mockPreferenceStorage, mockLocationService);
            var stores = new List<Store>();
            for (int i = 0; i < 9; i++)
            {
                stores.Add(new Store());
            }
            preferenceStorageMock.Setup(p => p.Get("newQuery", true)).Returns(true);
            preferenceStorageMock.Setup(p => p.Get("Latitude", double.MaxValue)).Returns(Double.MaxValue);
            preferenceStorageMock.Setup(p => p.Get("isLocationOpened", "true")).Returns("false");
            beijingCacheServiceMock.Setup(p => p.BeijingInitialized()).Returns(false);
            beijingCacheServiceMock.Setup(p =>
                    p.GetBeijingStoreByTagAsync("美食;" + tag.CnName, It.IsAny<int>(), StoreService.PageSize))
                .ReturnsAsync(stores);
            var statusList = new List<string>();

            var indexPageViewModel =
                new IndexPageViewModel(null, null,
                    mockPreferenceStorage, mockBeijingCacheService, mockLocationService);
            indexPageViewModel.Tag = tag;
            indexPageViewModel.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == nameof(TabbedTemplate.ViewModels.IndexPageViewModel.Status))
                {
                    statusList.Add(indexPageViewModel.Status);
                }
            };
            await indexPageViewModel.GetStoresFromWebCommandFunctionAsync();
            Assert.AreEqual(statusList[1], IndexPageViewModel.NoMoreResult);
        }

        [Test]
        public async Task TestPageAppearingCommandChangeCityBySelf()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var locationMock = new Mock<ILocationService>();
            var mockLocationService = locationMock.Object;
            var storeServiceMock = new Mock<IStoreService>();
            var mockStoreService = storeServiceMock.Object;
            var tag = Tag.ChineseRestuarant;
            var indexPageViewModel =
                new IndexPageViewModel(mockStoreService, null,
                    mockPreferenceStorage, null, mockLocationService);
            indexPageViewModel.TagCnName = tag.CnName;

            var stores = new InfiniteScrollCollection<Store>();
            var stores1 = new List<Store>();
            for (int i = 0; i < 9; i++)
            {
                stores1.Add(new Store());
                stores.Add(new Store());
            }

            indexPageViewModel.StoreCollection = stores;
            storeServiceMock.Setup(p =>
                p.SearchStoresByRegionFromWebAsync("美食;" + tag.CnName, "沈阳市",
                    stores.Count / StoreService.PageSize)).ReturnsAsync(stores1);
            preferenceStorageMock.Setup(p => p.Get("newQuery", true)).Returns(true);
            preferenceStorageMock.Setup(p => p.Get("Latitude", double.MaxValue)).Returns(Double.MinValue);
            preferenceStorageMock.Setup(p => p.Get("isLocationOpened", "true")).Returns("false");
            preferenceStorageMock.Setup(p => p.Get("City", "北京市")).Returns("沈阳市");
            var statusList = new List<string>();


            indexPageViewModel.Tag = tag;
            indexPageViewModel.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == nameof(TabbedTemplate.ViewModels.IndexPageViewModel.Status))
                {
                    statusList.Add(indexPageViewModel.Status);
                }
            };
            await indexPageViewModel.GetStoresFromWebCommandFunctionAsync();
            Assert.AreEqual(statusList[1], IndexPageViewModel.NoMoreResult);
        }
        [Test]
        public async Task TestPerformSearchFunction()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var query = "测试";
            var TagCNName = "中餐厅";
            var punchNavigtionServiceMock = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigtionServiceMock.Object;

            var IndexPageViewModel = new IndexPageViewModel(null,
                mockPunchNavigationService, mockPreferenceStorage, null, null);
            IndexPageViewModel.TagCnName = TagCNName;
            await IndexPageViewModel.PerformSearchFunction(query);
            Assert.AreEqual("", IndexPageViewModel.Input);
        }

    }
}
